<?php


namespace App\Services;


use App\Models\HouseFeeConfig;
use App\Models\Meter;
use App\Models\Owner;
use App\Models\OwnerItem;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;

class OwnerItemService
{
    protected $meterService;

    public function __construct(MeterService $meterService)
    {
        $this->meterService = $meterService;
    }


    /**
     * 更新杂费返回更新成功或者失败
     * @param OwnerItem $bill
     * @return bool
     */
    public function updateOtherAmount(OwnerItem $bill)
    {
        $bool = DB::transaction(
            function () use ($bill) {
                $data = request()->all();
                unset($data['_token']);

                // 获取合同
                $owner = $bill->owner;

                // 生成以house_config_id为键 price为值的数组
                $arr = array_column($owner->config, "price", "house_config_id");
                // 索引值
                $index = 0;
                // 杂费详细信息
                $other_amount = [];
                // 杂费总金额
                $other_fee = 0;

                // 计算各项杂费，并且保存
                foreach ($data as $houseFeeConfigId => $nowMoney) {

                    $houseFeeConfig = HouseFeeConfig::query()->find($houseFeeConfigId);

                    // 获取上一次的抄表对象
                    if ($bill->total_amount) {  // 如果已经存在本期流水总金额，那么表示是更新抄表数据
                        $lastMeter = $this->meterService->getLastLastMeterByOwner($owner, $houseFeeConfig);
                    } else {
                        $lastMeter = $this->meterService->getLastMeterByOwner($owner, $houseFeeConfig);
                    }

                    $price = $arr[$houseFeeConfig->id]; // 单价
                    // 根据单价计算出本次的抄表数值
                    $nowMeter = big_number($nowMoney)->divide($price)->add($lastMeter->value);

                    // 杂费详细信息
                    $other_amount[$index]['fee'] = $nowMoney;
                    $other_amount[$index]['house_fee_config_id'] = $houseFeeConfig->id;
                    $other_amount[$index]['name'] = $houseFeeConfig->name;
                    $other_amount[$index]['type'] = $houseFeeConfig->type;
                    $other_amount[$index]['unit'] = $houseFeeConfig->unit;
                    $other_amount[$index]['price'] = $arr[$houseFeeConfig->id];
                    $other_amount[$index]['last_meter'] = $lastMeter->value;
                    $other_amount[$index]['now_meter'] = $nowMeter->getValue();  // 本期表读数
                    $other_amount[$index]['reading_num'] = $nowMeter->subtract($lastMeter->value)->getValue();  // 使用量

                    // 判断流水id是否存在, 流水id存在就更新原本的抄表数据，否则就新增一条抄表数据
                    if (Meter::query()->where('owner_item_id', $bill->id)->where(
                        'house_fee_config_id',
                        $houseFeeConfigId
                    )->exists()) {
                        Meter::query()->where('owner_item_id', $bill->id)
                            ->where('house_fee_config_id', $houseFeeConfigId)
                            ->update(
                                [
                                    'value' => $nowMoney,
                                    'house_fee_config_id' => $houseFeeConfigId,
                                ]
                            );
                    } else {
                        // 创建抄表数据
                        Meter::query()->create(
                            [
                                'value' => $nowMoney,
                                'house_fee_config_id' => $houseFeeConfigId,
                                'count' => $lastMeter->count + 1,
                                'meterable_id' => $lastMeter->meterable_id,
                                'meterable_type' => $lastMeter->meterable_type,
                                'owner_item_id' => $bill->id,
                            ]
                        );
                    }
                    // 计算杂费总金额
                    $other_fee = big_number($other_fee)->add($nowMoney)->getValue();
                    $index++;
                }

                // 保存杂费项
                $bill->other_amount = $other_amount;
                // 更新流水时间，设置为抄表时间
                $bill->updated_at = Carbon::now();
                // 计算总金额
                $bill->total_amount = big_number($bill->rent)->add($other_fee)->getValue();
                $bill->save();
                return true;
            }
        );

        if ($bool) {
            return true;
        }
        return false;
    }

    /**
     * 更新抄表数据
     * @param OwnerItem $bill
     * @return bool
     */
    public function updateMeter(OwnerItem $bill)
    {
        $bool = DB::transaction(
            function () use ($bill) {
                $data = request()->all();
                unset($data['_token']);

                // 获取合同
                $owner = $bill->owner;

                // 生成以house_config_id为键 price为值的数组
                $arr = array_column($owner->config, "price", "house_config_id");
                // 索引值
                $index = 0;
                // 杂费详细信息
                $other_amount = [];
                // 杂费总金额
                $other_fee = 0;

                // 计算各项杂费，并且保存
                foreach ($data as $houseFeeConfigId => $nowMeter) {

                    $houseFeeConfig = HouseFeeConfig::query()->find($houseFeeConfigId);

                    // 获取上一次的抄表对象
                    if ($bill->total_amount) {  // 如果已经存在本期流水总金额，那么表示是更新抄表数据
                        $lastMeter = $this->meterService->getLastLastMeterByOwner($owner, $houseFeeConfig);
                    } else {
                        $lastMeter = $this->meterService->getLastMeterByOwner($owner, $houseFeeConfig);
                    }

                    // 获取读数差值
                    $temp = big_number($nowMeter)->subtract($lastMeter->value);
                    $readingNum = $temp->getValue();
                    // 如果读数差值小于0报错
                    if ($readingNum < 0) {
                        return $this->failed("本期抄表读数不得小于上期抄表读数");
                    }
                    // 费用
                    $fee = $temp->multiply($arr[$houseFeeConfig->id])->getValue();

                    // 杂费详细信息
                    $other_amount[$index]['fee'] = $fee;
                    $other_amount[$index]['house_fee_config_id'] = $houseFeeConfig->id;
                    $other_amount[$index]['name'] = $houseFeeConfig->name;
                    $other_amount[$index]['type'] = $houseFeeConfig->type;
                    $other_amount[$index]['unit'] = $houseFeeConfig->unit;
                    $other_amount[$index]['price'] = $arr[$houseFeeConfig->id];
                    $other_amount[$index]['last_meter'] = $lastMeter->value;
                    $other_amount[$index]['now_meter'] = $nowMeter;
                    $other_amount[$index]['reading_num'] = $readingNum;

                    // 判断流水id是否存在, 流水id存在就更新原本的抄表数据，否则就新增一条抄表数据
                    if (Meter::query()->where('owner_item_id', $bill->id)->where(
                        'house_fee_config_id',
                        $houseFeeConfigId
                    )->exists()) {
                        Meter::query()->where('owner_item_id', $bill->id)
                            ->where('house_fee_config_id', $houseFeeConfigId)
                            ->update(
                                [
                                    'value' => $fee,
                                    'house_fee_config_id' => $houseFeeConfigId,
                                ]
                            );
                    } else {
                        // 创建抄表数据
                        Meter::query()->create(
                            [
                                'value' => $fee,
                                'house_fee_config_id' => $houseFeeConfigId,
                                'count' => $lastMeter->count + 1,
                                'meterable_id' => $lastMeter->meterable_id,
                                'meterable_type' => $lastMeter->meterable_type,
                                'owner_item_id' => $bill->id,
                            ]
                        );
                    }
                    // 计算杂费总金额
                    $other_fee = big_number($other_fee)->add($fee)->getValue();
                    $index++;
                }

                // 保存杂费项
                $bill->other_amount = $other_amount;
                // 更新流水时间，设置为抄表时间
                $bill->updated_at = Carbon::now();
                // 计算总金额
                $bill->total_amount = big_number($bill->rent)->add($other_fee)->getValue();
                $bill->save();
                return true;
            }
        );

        if ($bool) {
            return true;
        }
        return false;
    }

    /**
     * 管理员信息：计算本月已经入账营收
     * 备注：不会统计未抄表用户
     * @return double
     */
    public function getRentAlreadyIncomeThisMonth()
    {
        $totalAmount = OwnerItem::query()->whereNotNull('pay_at')
            ->where('pay_at', '>', \Carbon\Carbon::now()->startOfMonth())
            ->where('pay_at', '<', Carbon::now()->endOfMonth())
            ->sum('total_amount');

        return $totalAmount;
    }

    /**
     * 管理员信息：计算本月总应营收 = 已入账营收 + 未入账营收，
     * 备注：不会统计未抄表用户
     * @return double
     */
    public function getRentThisMonth()
    {
        $totalAmount = OwnerItem::query()
            ->where('pay_at', '>', \Carbon\Carbon::now()->startOfMonth())
            ->where('pay_at', '<', Carbon::now()->endOfMonth())
            ->sum('total_amount');

        return $totalAmount;
    }


    /**
     * 管理员信息： 获取最近30天即将到期合同
     * @return int
     */
    public function getLast30DaysExpiredContractsCount()
    {
        $count = Owner::query()->where([
            ['ended_at', '<', \Carbon\Carbon::now()->addDays(30)],
            ['ended_at', '>', Carbon::now()]
        ])->count();

        return $count;
    }

    /**
     * 用户信息： 获取流水账单的收费月份
     * @param OwnerItem $ownerItem
     * @return mixed
     */
    public function getOwnerItemMonth(OwnerItem $ownerItem)
    {
        return \Carbon\Carbon::parse($ownerItem->ended_at)->month;
    }


    /**
     * 用户信息： 获取流水账单的租金
     * @param OwnerItem $ownerItem
     * @return double|string
     */
    public function getOwnerItemRent(OwnerItem $ownerItem)
    {
        return $ownerItem->rent;
    }

    /**
     * 用户信息： 计算一次性收费金额
     * @param OwnerItem $ownerItem
     * @return double|string
     */
    public function getOwnerItemOtherOnce(OwnerItem $ownerItem)
    {
        return big_number($ownerItem->total_amount)->subtract($ownerItem->rent)->getValue();
    }

    /**
     * 正常合同的金额计算： （本期抄表数 - 上期抄表数据）* 配置项的单价 + 租金 + 一次性收费项 + 周期性付费
     * 一般用于最后一期合同流水账单的计算
     * @param OwnerItem $ownerItem
     */
//    public function sumDefaultContractAmount(OwnerItem $ownerItem, $meter) {
//        // 实例化抄表服务
//        $meterService = new MeterService();
//
//        // 获取上期的抄表数据
//        $meterByOwnerItem = $meterService->getLastMeterByOwnerItem($ownerItem);
//
//        // 获取上期的抄表数据
//        $meterService->
//
//    }

}